package com.cskaoyan.javase.oop2.encapsulate._0introduction;

/**
 * 封装是面向对象编程思想中必不可少的一环，狭义上来说：
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。
 * 在Java或者C++中，类就是这样一种结构，所以它们具有封装的面向对象语言特性。当然，没有类就不能封装吗？
 * 当然不是，只要将数据和操作看成绑定在一起的结构，C语言（结构体）也能写面向对象思想的程序。
 *
 * 封装的目的/意义：
 * 封装是为了将数据保护在内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 * 此接口非彼接口,这里说得接口就是内部和外部进行交互的一个方式,不是Java语法中的接口
 *
 * 更进一步来说
 * 是为了将代码的使用者和实现者分开。使用者能够完全得到自己想要的功能，又不需要思考过多细节；
 * 实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 * 对于Java而言，封装的实现是离不开访问权限修饰符的辅助的。
 *
 *
 * 封装的思想告诉我们：
 * 数据尽量不要让外部直接访问，而是提供一些方法（“接口”）有选择地、可控制地让外界访问。
 * 为了避免让外界直接访问一个内部的数据,应该去私有化它
 * 这时,外界就不能用常规手段访问到它了
 * 在需要的时候,在设计类时,可以给外界提供一个受控制的,有限的访问,指的是:
 *      Java当中的Getter/Setter方法
 *
 * 提供一个外界有限的访问方法: Getter方法
 * 提供一个外界有限的赋值方法: Setter方法
 *
 * Getter/Setter方法语法格式是非常固定的,所以快捷键alt+insert来生成它,如无必要,不要手写
 *
 * 浅谈Getter/Setter方法的优点:
 *      1.在没有Getter/Setter方法之前,成员变量的读写都依赖于"对象名."
 *          它们的读写是完全一体的
 *          而Getter/Setter方法将它们的读写进行了分离
 *      2.Getter/Setter方法可以有选择的生成,根据需要生成,并不是说必须的
 *          Getter/Setter方法的使用,是有选择权力的
 *
 *      3.Getter/Setter方法,既然是方法,那么就可以控制访问和赋值,对比之前是控制不了的
 *          (实际开发中很少有这么做的,建议不要这么做)
 *
 *
 *
 * @since 16:04
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // s.age
        System.out.println(s.getAge());
        s.setAge(180);
        System.out.println(s.getAge());
    }
}

class Student {
    private int age;
    private String name;

    // age的Getter方法,用于外界进行访问
    public int getAge() {
        return age;
    }

    // age的Setter方法,用于外界进行赋值
    public void setAge(int age) {
        // this.age = age;
        if (age < 1) {
            System.out.println("你不能活到过去吧?");
            return;
        }
        if (age > 120) {
            System.out.println("您这还是挺厉害的!");
            return;
        }
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
